﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using PerfilEmpreendedor.Dao.Interfaces;
using PerfilEmpreendedor.Dao.Factory;
using PerfilEmpreendedor.Bo.Model;
using Ext.Net;

namespace PerfilEmpreendedor.FrontEnd
{
    public partial class Jogar : PerfilEmpreendedorPage
    {
        private DaoFactory daoFactory = DaoFactory.GetInstance;
        protected IList<Usuario> Fila
        {
            get
            {
                IList<Usuario> lst = new List<Usuario>();
                lst.Add(new Usuario());
                IPartidaDao partidaDao = daoFactory.GetPartidaDao;
                Partida p = partidaDao.Find(Convert.ToInt32(Request["id"]));
                for (int i = 0; i < 100; i++)
                {
                    foreach (var item in p.Jogadores.OrderBy(x => x.Posicao))
                    {
                        lst.Add(item.Jogador);
                    }
                }
                return lst;
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {

            }

        }
        protected void ListarPontuacao(Int32 idPartida)
        {
            IPartidaDao partidaDao = daoFactory.GetPartidaDao;
            storePontuacao.DataSource = partidaDao.ListarPontuacao(idPartida);
            storePontuacao.DataBind();

            storePontuacao.Sort("Pontos", Ext.Net.SortDirection.DESC);
            CarregarAcoes(Convert.ToInt32(Request["id"]));

        }
        protected void CarregarAcoes(int IdPartida)
        {
            IAcaoDao acaoDao = daoFactory.GetAcaoDao;
            storeAcoes.DataSource = acaoDao.ObterAcoesPorPartida(IdPartida);
            storeAcoes.DataBind();
        }
        public void CarregarTabelas()
        {
            ITipoCartelaDao tipoCartelaDao = daoFactory.GetTipoCartelaDao;
            selectTipo.Store[0].DataSource = tipoCartelaDao.List("Descricao");
            selectTipo.Store[0].DataBind();
        }
        protected void CarregarPartida(Int32 idPartida)
        {
            IHistoricoDao historicoDao = daoFactory.GetHistoricoDao;
            Historico ultimaJogada = historicoDao.ObterUltimaJogada(idPartida);
            if (ultimaJogada != null)
            {
                if (!ultimaJogada.Finalizado)
                {
                    if (ultimaJogada.Jogador.Id == IdUserLogado)
                    {
                        hiddenIdHistorico.Text = ultimaJogada.Id.ToString();
                        txtTipo.Text = ultimaJogada.Cartela.Tipo.Descricao;
                        btnVisualizarDica.Disabled = ultimaJogada.Dicas.Count > 9;
                        VisualizarDicasEscolhidas(ultimaJogada);
                        formResponderCartela.Show();
                        timer.StopAll();
                    }

                }
                else
                {
                    if (ultimaJogada.Jogador.Id == IdUserLogado && ultimaJogada.Acertou)
                    {
                        int proximaPosicao = ultimaJogada.Partida.PosicaoAtual + 1;

                        hiddenProximaPosicao.Text = proximaPosicao.ToString();
                        Usuario proximoJogador = Fila[proximaPosicao];
                        hiddenProximoJogador.Text = proximoJogador.Id.ToString();
                        txtJogador.Text = proximoJogador.Login;
                        formEscolherCartela.Show();
                        timer.StopAll();
                    }
                }
            }


        }
        protected void ListarCartelas(Object sender, DirectEventArgs e)
        {
            IHistoricoDao historicoDao = daoFactory.GetHistoricoDao;
            Historico ultimaJogada = historicoDao.ObterUltimaJogada(Convert.ToInt32(hiddenPartida.Text));
            ICartelaDao cartelaDao = daoFactory.GetCartelaDao;
            IList<Cartela> lst = cartelaDao.ListarParaJogo(ultimaJogada.Partida, Convert.ToInt32(selectTipo.SelectedItem.Value));
            storeCartelas.DataSource = lst;
            storeCartelas.DataBind();
            if (lst.Count > 0)
            {
                statusCartelas.Text = "Total de cartelas disponíveis: " + lst.Count.ToString();
            }
            else
            {
                statusCartelas.Text = "cartelas não disponíveis para este tema.";
            }
        }
        private void VisualizarDicasEscolhidas(Historico h)
        {
            //TODO: Resolver bug da visualização de dicas

            IHistoricoDao historicoDao = daoFactory.GetHistoricoDao;
            Historico historico = historicoDao.Find(h.Id);
            storeDicas.DataSource = historico.Dicas;
            storeDicas.DataBind();

        }
        protected void VisualizarDica(Object sender, DirectEventArgs e)
        {
            IHistoricoDao historicoDao = daoFactory.GetHistoricoDao;
            Historico historico = historicoDao.Find(Convert.ToInt32(hiddenIdHistorico.Text));
            if (historico.JogadorDaUltimaDica == null || historico.JogadorDaUltimaDica.Id != IdUserLogado)
            {
                Boolean valeu = false;
                while (!valeu)
                {
                    Dica selecionada = historico.Cartela.Dicas[new Random().Next(0, historico.Cartela.Dicas.Count)];
                    if (historico.Dicas.Count(x => x.Id == selecionada.Id) < 1)
                    {
                        historico.Dicas.Add(selecionada);
                        historico.JogadorDaUltimaDica = new Usuario() { Id = IdUserLogado };
                        historicoDao.Update(historico);
                        btnVisualizarDica.Disabled = historico.Dicas.Count > 9;
                        valeu = true;
                    }
                }
            }
            else
            {
                ExtFunctions.Alert("Você já visualizou uma dica nesta jogada", MessageBox.Icon.ERROR);
            }
            VisualizarDicasEscolhidas(historico);
        }
        protected void Responder(Object sender, DirectEventArgs e)
        {
            IHistoricoDao historicoDao = daoFactory.GetHistoricoDao;
            Historico historico = historicoDao.Find(Convert.ToInt32(hiddenIdHistorico.Text));
            historico.Acertou = historico.Cartela.Resposta.ToUpper().Equals(txtResposta.Text.ToUpper());
            Acao acao = new Acao();
            acao.Data = DateTime.Now;
            acao.Partida = historico.Partida;
            IAcaoDao acaoDao = daoFactory.GetAcaoDao;
            if (TempoEsgotado(historico))
            {
                ExtFunctions.Alert("Tempo esgotado. A cartela será repassada para o próximo jogador.", MessageBox.Icon.INFO);

                acao.Descricao = "Tempo esgotado para resposta.O jogador " + historico.Jogador.Login + " repassou a cartela.";
                acaoDao.Save(acao);

                Repassar(historico);

            }
            else
            {
                if (historico.Acertou)
                {
                    ExtFunctions.Alert("Resposta certa", MessageBox.Icon.INFO);
                    historico.Finalizado = true;
                    historicoDao.Update(historico);

                    acao.Descricao = "O jogador " + historico.Jogador.Login + " respondeu corretamente.";
                    acaoDao.Save(acao);
                }
                else
                {
                    //Repassa para o próximo jogador
                    ExtFunctions.Alert("Resposta incorreta. A cartela será repassada para o próximo jogador.", MessageBox.Icon.INFO);

                    acao.Descricao = "Resposta incorreta. O jogador " + historico.Jogador.Login + " repassou a cartela.";
                    acaoDao.Save(acao);

                    Repassar(historico);

                }
            }
            formResponderCartela.Hide();
            timer.StartAll();
        }
        protected void Repassar(Historico historico)
        {
            int proximaPosicao = 0;

            proximaPosicao = historico.Partida.PosicaoAtual + 1;

            if (historico.Emissor != null && historico.Emissor.Id == Fila[proximaPosicao].Id)
            {
                proximaPosicao = historico.Partida.PosicaoAtual + 2;
            }
            historico.Partida.PosicaoAtual = proximaPosicao;
            historico.Jogador = Fila[proximaPosicao];
            historico.DataPergunta = DateTime.Now;
            IHistoricoDao historicoDao = daoFactory.GetHistoricoDao;
            historicoDao.Update(historico);

            IPartidaDao partidaDao = daoFactory.GetPartidaDao;
            partidaDao.Update(historico.Partida);
        }
        protected Boolean TempoEsgotado(Historico h)
        {
            DateTime dtPergunta = h.DataPergunta.AddMinutes(Convert.ToDouble(h.Partida.TempoDeResposta));
            TimeSpan tempoRestante = dtPergunta.Subtract(DateTime.Now);
            return tempoRestante.Ticks < 0;
        }
        protected void OnGridCommand(Object sender, DirectEventArgs e)
        {
            IUsuarioDao usuarioDao = daoFactory.GetUsuarioDao;
            Historico historico = new Historico()
            {
                Cartela = new Cartela() { Id = Convert.ToInt32(e.ExtraParams["Id"]) },
                Partida = new Partida() { Id = Convert.ToInt32(hiddenPartida.Text) },
                Jogador = usuarioDao.Find(Convert.ToInt32(hiddenProximoJogador.Text)),
                Emissor = new Usuario() { Id = IdUserLogado },
                DataPergunta = DateTime.Now,
                Finalizado = false,
                Acertou = false
            };
            IHistoricoDao historicoDao = daoFactory.GetHistoricoDao;

            IPartidaDao partidaDao = daoFactory.GetPartidaDao;
            Partida p = partidaDao.Find(historico.Partida.Id);
            p.PosicaoAtual = Convert.ToInt32(hiddenProximaPosicao.Text);


            Acao acao = new Acao();
            acao.Data = DateTime.Now;
            acao.Partida = historico.Partida;
            IAcaoDao acaoDao = daoFactory.GetAcaoDao;
            acao.Descricao = "Nova cartela lançada para o jogador " + historico.Jogador.Login;

            historicoDao.Save(historico);
            partidaDao.Update(p);
            acaoDao.Save(acao);


            ExtFunctions.Alert("Cartela seleconada", MessageBox.Icon.INFO);
            formEscolherCartela.Hide();
            timer.StartAll();

        }
        protected void OnTaskUpdate(Object sender, DirectEventArgs e)
        {
            if (Request["id"] != null)
            {
                Int32 idPartidaAtual = Convert.ToInt32(Request["id"]);
                IPartidaDao partidaDao = daoFactory.GetPartidaDao;
                Partida p = partidaDao.Find(idPartidaAtual);
                ListarPontuacao(idPartidaAtual);
                if (p.Finalizada)
                {
                    ExtFunctions.Alert("Partida Finalizada", MessageBox.Icon.INFO);
                    timer.StopAll();
                }
                else
                {
                    CarregarPartida(idPartidaAtual);
                    CarregarTabelas();
                    hiddenPartida.Text = idPartidaAtual.ToString();
                }
            }
            else
            {
                Response.Redirect("Default.aspx");
            }
        }
    }
}